/**
*****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-8-28 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-8-28		Created.
 ****************************************************************************
**/
package com.me.test.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 
 * <br/> 下午5:33:02 2012-8-28
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class ServerMe {
	
	private Selector selector = null;
	private ByteBuffer readBuffer = ByteBuffer.allocate(8);
	private Map<SocketChannel, byte[]> clientMessage = new ConcurrentHashMap<SocketChannel, byte[]>();
	
	public static void main(String[] args) throws IOException {
		System.out.println("server started...");
		new ServerMe().start();
	}

	private void start() throws IOException {
		ServerSocketChannel ssc = ServerSocketChannel.open();
		ssc.configureBlocking(false);
		ssc.socket().bind(new InetSocketAddress("127.0.0.1", 8001));
		selector = Selector.open();
		ssc.register(selector, SelectionKey.OP_ACCEPT);
		while(!Thread.currentThread().isInterrupted()){
			selector.select();
			Set<SelectionKey> keySet = selector.selectedKeys();
			Iterator<SelectionKey> keyIterator = keySet.iterator();
			while(keyIterator.hasNext()){
				SelectionKey key = keyIterator.next();
				if(!key.isValid()){
					continue;
				}
				if(key.isAcceptable()){
					accept(key);
				}else if(key.isReadable()){
					read(key);
				}
				keyIterator.remove();
			}
		}
	}

	private void read(SelectionKey key) throws IOException {
		SocketChannel sc = (SocketChannel)key.channel();
		this.readBuffer.clear();
		int numRead = 0;
		try {
			numRead = sc.read(readBuffer);
		} catch (IOException e) {
			e.printStackTrace();
			key.cancel();
			sc.close();
			clientMessage.remove(sc);
			return;
		}
		byte[] bytes = clientMessage.get(sc);
		if(bytes == null){
			bytes = new byte[0];
		}
		if(numRead > 0){
			byte[] newBytes = new byte[bytes.length + numRead];
			System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
			System.arraycopy(readBuffer.array(), 0, newBytes, bytes.length, numRead);
			clientMessage.put(sc, newBytes);
			 System.out.println(new String(newBytes));
		}else{
			
		}
	}

	private void accept(SelectionKey key) throws IOException {
		// TODO Auto-generated method stub
		ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
		SocketChannel sc = ssc.accept();
		sc.configureBlocking(false);
		sc.register(selector, SelectionKey.OP_READ);
		System.out.println("---------a new client connected--------");
	}

}
